Data Visualization
Turnout
age <- demo_turnout %>%
ggplot(aes(x = Date)) +
geom_line(aes(y = Age_18to29, color = "18 to 29")) +
geom_line(aes(y = Age_30to44, color = "30 to 44")) +
geom_line(aes(y = Age_45to59, color = "45 to 59")) +
geom_line(aes(y = Age_60plus, color = "60 plus")) +
labs(y = "Turnout Rate", title = "Turnout by Age", color = "Age") +
theme_minimal() +
theme(legend.position="bottom")
#ggsave("demo_age.png")
ethnicity <- demo_turnout %>%
ggplot(aes(x = Date)) +
geom_line(aes(y = Ethicity_NonHispanic_White, color = "Non-Hispanic White")) +
geom_line(aes(y = Ethnicity_NonHispanic_Black, color = "Non-Hispanic Black")) +
geom_line(aes(y = Ethnicity_Hispanic, color = "Hispanic")) +
geom_line(aes(y = Ethnicity_Other, color = "Other")) +
labs(y = "Turnout Rate", title = "Turnout by Race and Ethnicity", color = "Race and Ethnicity") +
theme_minimal() +
theme(legend.position="bottom")
#ggsave("demo_eth.png")
education <- demo_turnout %>%
ggplot(aes(x = Date)) +
geom_line(aes(y = Education_Less_Than_HS, color = "Less than High School")) +
geom_line(aes(y = Education_HS_Grad, color = "High School Grad")) +
geom_line(aes(y = Education_SomeCollege_CollegeGrad, color = "Some College or College Grad")) +
geom_line(aes(y = Education_PostGraduate, color = "Post Graduate")) +
labs(y = "Turnout Rate", title = "Turnout by Education", color = "Education") +
theme_minimal() +
theme(legend.position="bottom")
#ggsave("demo_edu.png")
The other turnout graphs can be found here.
Economy
nat_gdp_plot <- nat_gdp %>%
ggplot(aes(x = Date, y = GDP)) +
geom_line() +
labs(x = "Date", y = "GDP (Billions)", title = "National GDP over Time, Quarterly") +
theme_minimal()
ggplotly(nat_gdp_plot)
us_map <- map_data(map = "state") %>%
mutate(region = str_to_title(region))
gdp_map <- us_map %>%
left_join(state_gdp_employment, by = c("region" = "State")) %>%
filter(Type_of_Value == "Gross domestic product (GDP)")
p_test_2 <- gdp_map %>%
ggplot(aes(x = long, y = lat, group = group)) +
geom_polygon(aes(fill = (Value/1000))) +
scale_fill_gradient(low = "aliceblue", high = "midnightblue", name = "GDP (Billions)") +
coord_map("polyconic") +
theme_map() +
ggtitle("GDP in {1997 + frame}") +
transition_manual(Year)
#animate(p_test_2, nframes = 50)
#anim_save("state_gdp.gif")
employment_map <- us_map %>%
left_join(state_gdp_employment, by = c("region" = "State")) %>%
filter(Type_of_Value == "Total Employment (number of jobs)")
p_test_2 <- gdp_map %>%
ggplot(aes(x = long, y = lat, group = group)) +
geom_polygon(aes(fill = (Value))) +
scale_fill_gradient(low = "honeydew", high = "darkslategray", name = "Number of Jobs") +
coord_map("polyconic") +
theme_map() +
ggtitle("Employment in {1997 + frame}") +
transition_manual(Year)
#animate(p_test_2, nframes = 50)
#anim_save("state_employment.gif")
Weather
nat_turnout_for_plot <- nat_turnout %>%
filter(Year > 1895) %>%
mutate(Date = as.Date(as.character(Year), "%Y"))
# turnout_plus_weather <- nat_turnout %>%
# filter(Year > 1895) %>%
# mutate(Date = as.Date(as.character(Year), "%Y")) %>%
# full_join(nat_precip, by = "Date") %>%
# (Date)
fig <- plot_ly(nat_precip)
fig <- fig %>%
add_trace(x = ~Date, y = ~Precipitation, type = "scatter", mode = "lines", name = "November Precipiation")
fig <- fig %>%
add_trace(nat_turnout_for_plot, x = ~nat_turnout_for_plot$Date, y = ~nat_turnout_for_plot$Turnout, name = "Turnout", type = "scatter", yaxis = "y2", mode = "lines")
fig <- fig %>% layout(
title = "Precipitation and Weather",
xaxis = list(title = "Date"),
yaxis = list(title = "Precipitation"),
yaxis2 = list(overlaying = "y", side = "right", title = "Turnout Rate"),
hovermode = "x"
)
fig
nat_precip_plot <- nat_precip %>%
ggplot(aes(x = Date, y = Precipitation)) +
geom_line() +
scale_y_continuous(name = "Precipitation", sec.axis = sec_axis(~.*10, name = "Turnout")) +
scale_x_date(breaks = '25 years', date_labels = "%Y") +
labs(x = "Date", y = "Precipitation", title = "November Precipitation") +
theme_minimal()
ggplotly(nat_precip_plot)
weather_map <- us_map %>%
left_join(state_weather, by = c("region" = "State"))
p_weather <- weather_map %>%
ggplot(aes(x = long, y = lat, group = group)) +
geom_polygon(aes(fill = Precipitation)) +
scale_fill_gradient(low = "floralwhite", high = "darkred", name = "Precipitation (In)") +
coord_map("polyconic") +
theme_map() +
ggtitle("November Precipitation in {1894 + frame}") +
transition_manual(Date)
#animate(p_weather, nframes = 200)
#anim_save("state_weather.gif")
EDA
Turnout
# Initial Time Series Plot
nat_turnout_plot <- nat_turnout %>%
ggplot(aes(x = Year, y = Turnout)) +
geom_line() +
scale_y_continuous(labels = scales::label_comma(suffix = '%')) +
labs(title = "National Turnout Over Time") +
theme_minimal()
ggplotly(nat_turnout_plot)
# TS Object
turnout_ts <- ts(nat_turnout$Turnout, start = 1788, frequency = 0.5)
# Lag Plot
gglagplot(turnout_ts, lags = 12, do.lines = FALSE)

# Decomposed Plot
# Not able to decompose - fewer than 2 periods because it's every 2 years
# Can see the trend from plotting presidential and midterm separately
nat_turnout_plot_decomposed <- nat_turnout %>%
ggplot(aes(x = Year, y = Turnout)) +
geom_line(aes(color = Type)) +
scale_y_continuous(labels = scales::label_comma(suffix = '%')) +
scale_color_manual(values = c("darkgreen", "purple")) +
labs(title = "National Turnout Over Time - Trend Lines") +
theme_minimal()
ggplotly(nat_turnout_plot_decomposed)
NA
# ACF and PACF
turnout_acf <- ggAcf(turnout_ts, 20) +
labs(x = "Lag", y = "ACF", title = "Turnout ACF Plot") +
theme_minimal()
turnout_pacf <- ggPacf(turnout_ts, 20) +
labs(x = "Lag", y = "PACF", title = "Turnout PACF Plot") +
theme_minimal()
grid.arrange(turnout_acf, turnout_pacf, ncol = 2)

# Moving Average Smoothing
m5 <- autoplot(turnout_ts, color = 'darkblue') +
autolayer(ma(turnout_ts, 5), color = 'red') +
labs(x = "Date", y = "Turnout Rate", title = "Turnout (MA-5)") +
theme_minimal()
m10 <- autoplot(turnout_ts, color = 'darkblue') +
autolayer(ma(turnout_ts, 10), color = 'red') +
labs(x = "Date", y = "Turnout Rate", title = "Turnout (MA-10)") +
theme_minimal()
m25 <- autoplot(turnout_ts, color = 'darkblue') +
autolayer(ma(turnout_ts, 20), color = 'red') +
labs(x = "Date", y = "Turnout Rate", title = "Turnout (MA-20)") +
theme_minimal()
m50 <- autoplot(turnout_ts, color = 'darkblue') +
autolayer(ma(turnout_ts, 50), color = 'red') +
labs(x = "Date", y = "Turnout Rate", title = "Turnout (MA-50)") +
theme_minimal()
grid.arrange(m5, m10, m20, m50, nrow = 2)

Economic Conditions
# Initial Time Series Plot
nat_gdp_plt <- nat_gdp %>%
ggplot(aes(x = Date, y = GDP)) +
geom_line() +
labs(title = "National GDP Over Time") +
theme_minimal()
ggplotly(nat_gdp_plt)
# TS Object
gdp_ts <- ts(nat_gdp$GDP, start = c(1947, 1), frequency = 4)
# Lag Plot
gglagplot(gdp_ts, lags = 12, do.lines = FALSE)
# Decomposed Plot
decomposed_gdp = decompose(gdp_ts, "multiplicative")
autoplot(decomposed_gdp)
# ACF and PACF
gdp_acf <- ggAcf(gdp_ts, 30) +
labs(x = "Lag", y = "ACF", title = "GDP ACF Plot") +
theme_minimal()
gdp_pacf <- ggPacf(gdp_ts, 30) +
labs(x = "Lag", y = "PACF", title = "GDP PACF Plot") +
theme_minimal()
grid.arrange(gdp_acf, gdp_pacf, ncol = 2)
# ADF Test
tseries::adf.test(gdp_ts)
# Differenced/Log Transformed
p11 <- autoplot(gdp_ts) +
labs(x = "Year", y = "GDP", title = "Original GDP") +
theme_minimal()
p22 <- autoplot(diff(gdp_ts)) +
labs(x = "Year", y = "Diff(GDP)", title = "First-Order Differenced GDP") +
theme_minimal()
p33 <- autoplot(log(gdp_ts)) +
labs(x = "Year", y = "Log(GDP)", title = "Log-Transformed GDP") +
theme_minimal()
grid.arrange(p11, p22, p33, ncol = 1)
# ACF Compare
p11_acf <- ggAcf(gdp_ts, 20) +
labs(x = "Lag", y = "ACF", title = "Original GDP ACF Plot") +
theme_minimal()
p22_acf <- ggAcf(diff(gdp_ts), 20) +
labs(x = "Lag", y = "ACF", title = "First-Order Differenced GDP ACF Plot") +
theme_minimal()
p33_acf <- ggAcf(log(gdp_ts), 20) +
labs(x = "Lag", y = "ACF", title = "Log-Transformed GDP ACF Plot") +
theme_minimal()
grid.arrange(p11_acf, p22_acf, p33_acf, ncol = 1)
# Moving Average Smoothing
m5 <- autoplot(gdp_ts, color = 'darkblue', size = 0.75) +
autolayer(ma(gdp_ts, 5), color = 'red') +
labs(x = "Date", y = "GDP", title = "National GDP (MA-5)") +
theme_minimal()
m20 <- autoplot(gdp_ts, color = 'darkblue', size = 0.75) +
autolayer(ma(gdp_ts, 20), color = 'red') +
labs(x = "Date", y = "GDP", title = "National GDP (MA-20)") +
theme_minimal()
m50 <- autoplot(gdp_ts, color = 'darkblue', size = 0.75) +
autolayer(ma(gdp_ts, 50), color = 'red') +
labs(x = "Date", y = "GDP", title = "National GDP (MA-50)") +
theme_minimal()
m100 <- autoplot(gdp_ts, color = 'darkblue', size = 0.75) +
autolayer(ma(gdp_ts, 100), color = 'red') +
labs(x = "Date", y = "GDP", title = "National GDP (MA-100)") +
theme_minimal()
grid.arrange(m5, m20, m50, m100, nrow = 2)

Weather
# Initial Time Series Plot
nat_precip_plt <- nat_precip %>%
ggplot(aes(x = Date, y = Precipitation)) +
geom_line() +
labs(title = "National Precipitation Over Time") +
theme_minimal()
ggplotly(nat_precip_plt)
# TS Object
precip_ts <- ts(nat_precip$Precipitation, start = 1895, frequency = 1)
# Lag Plot
gglagplot(precip_ts, lags = 12, do.lines = FALSE)
# Decomposed Plot
# Not able to do - only one every year
# ACF and PACF
precip_acf <- ggAcf(precip_ts, 30) +
labs(x = "Lag", y = "ACF", title = "Precipitation ACF Plot") +
theme_minimal()
precip_pacf <- ggPacf(precip_ts, 30) +
labs(x = "Lag", y = "PACF", title = "Precipitation PACF Plot") +
theme_minimal()
grid.arrange(precip_acf, precip_pacf, ncol = 2)
# ADF Test
tseries::adf.test(precip_ts)
# Moving Average Smoothing
m5 <- autoplot(precip_ts, color = 'darkblue', size = 0.75) +
autolayer(ma(precip_ts, 5), color = 'red') +
labs(x = "Date", y = "Precipitation", title = "National Precipitation (MA-5)") +
theme_minimal()
m10 <- autoplot(precip_ts, color = 'darkblue', size = 0.75) +
autolayer(ma(precip_ts, 10), color = 'red') +
labs(x = "Date", y = "Precipitation", title = "National Precipitation (MA-10)") +
theme_minimal()
m20 <- autoplot(precip_ts, color = 'darkblue', size = 0.75) +
autolayer(ma(precip_ts, 20), color = 'red') +
labs(x = "Date", y = "Precipitation", title = "National Precipitation (MA-20)") +
theme_minimal()
m50 <- autoplot(precip_ts, color = 'darkblue', size = 0.75) +
autolayer(ma(precip_ts, 50), color = 'red') +
labs(x = "Date", y = "Precipitation", title = "National Precipitation (MA-50)") +
theme_minimal()
grid.arrange(m5, m10, m20, m50, nrow = 2)

LS0tCnRpdGxlOiAiRURBIGFuZCBEYXRhIFZpeiBQbG90cyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShtYXBzKQpsaWJyYXJ5KGdnYW5pbWF0ZSkKbGlicmFyeSh0cmFuc2Zvcm1yKQpsaWJyYXJ5KGdndGhlbWVzKQpsaWJyYXJ5KGdpZnNraSkKbGlicmFyeShwbmcpCgpybShsaXN0ID0gbHMoKSkKYGBgCgpgYGB7cn0KY2Vuc3VzX3ZvdGVycyA9IHJlYWQuY3N2KCJkYXRhL2NlbnN1c192b3RlcnNfYWdncmVnYXRlcy5jc3YiKQpkZW1vX3R1cm5vdXQgPSByZWFkLmNzdigiZGF0YS9EZW1vX1R1cm5vdXRfcmF0ZXMuY3N2IikKbmF0X3ByZWNpcCA9IHJlYWQuY3N2KCJkYXRhL05hdF9QcmVjaXAuY3N2IikgJT4lCiAgbXV0YXRlKERhdGUgPSBhcy5EYXRlKERhdGUsICIlWS0lbS0lZCIpKQpuYXRfZ2RwID0gcmVhZHhsOjpyZWFkX2V4Y2VsKCJkYXRhL05hdGlvbmFsX0dEUC54bHN4IikgJT4lCiAgbXV0YXRlKERhdGUgPSBhcy5EYXRlKERhdGUsICIlWS0lbS0lZCIpKQpuYXRfdHVybm91dCA9IHJlYWQuY3N2KCJkYXRhL05hdGlvbmFsX1R1cm5vdXRfMTc4OV8yMDE4LmNzdiIpCnN0YXRlX2dkcF9lbXBsb3ltZW50ID0gcmVhZC5jc3YoImRhdGEvU3RhdGVfR0RQX2VtcGxveW1lbnQuY3N2IikKc3RhdGVfd2VhdGhlciA9IHJlYWQuY3N2KCJkYXRhL3N0YXRlX3dlYXRoZXIuY3N2IikKc3RhdGVfdHVybm91dCA9IHJlYWQuY3N2KCJkYXRhL1R1cm5vdXRfYnlfc3RhdGUuY3N2IikgJT4lCiAgbXV0YXRlKERhdGUgPSBhcy5EYXRlKERhdGUsICIlbS8lZC8leSIpKQpgYGAKCmBgYHtyfQpzdGF0ZV9nZHBfZW1wbG95bWVudCA8LSByZXNoYXBlMjo6bWVsdChzdGF0ZV9nZHBfZW1wbG95bWVudCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkID0gYygiR2VvTmFtZSIsIkRlc2NyaXB0aW9uIikpICU+JQogIHJlbmFtZShTdGF0ZSA9IEdlb05hbWUsIFR5cGVfb2ZfVmFsdWUgPSBEZXNjcmlwdGlvbiwgCiAgICAgICAgIFllYXIgPSB2YXJpYWJsZSwgVmFsdWUgPSB2YWx1ZSkgJT4lCiAgbXV0YXRlKFllYXIgPSB5ZWFyKGFzLkRhdGUoZ3N1YignWCcsJycsIFllYXIpLCAiJVkiKSkpICU+JQogIG11dGF0ZShUeXBlX29mX1ZhbHVlID0gc3Vic3RyaW5nKFR5cGVfb2ZfVmFsdWUsIDMpKQpgYGAKCiMgRGF0YSBWaXN1YWxpemF0aW9uCgojIyBUdXJub3V0CgpgYGB7cn0KYWdlIDwtIGRlbW9fdHVybm91dCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBEYXRlKSkgKwogIGdlb21fbGluZShhZXMoeSA9IEFnZV8xOHRvMjksIGNvbG9yID0gIjE4IHRvIDI5IikpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBBZ2VfMzB0bzQ0LCBjb2xvciA9ICIzMCB0byA0NCIpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gQWdlXzQ1dG81OSwgY29sb3IgPSAiNDUgdG8gNTkiKSkgKwogIGdlb21fbGluZShhZXMoeSA9IEFnZV82MHBsdXMsIGNvbG9yID0gIjYwIHBsdXMiKSkgKwogIGxhYnMoeSA9ICJUdXJub3V0IFJhdGUiLCB0aXRsZSA9ICJUdXJub3V0IGJ5IEFnZSIsIGNvbG9yID0gIkFnZSIpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikKI2dnc2F2ZSgiZGVtb19hZ2UucG5nIikKCmV0aG5pY2l0eSA8LSBkZW1vX3R1cm5vdXQgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRGF0ZSkpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBFdGhpY2l0eV9Ob25IaXNwYW5pY19XaGl0ZSwgY29sb3IgPSAiTm9uLUhpc3BhbmljIFdoaXRlIikpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBFdGhuaWNpdHlfTm9uSGlzcGFuaWNfQmxhY2ssIGNvbG9yID0gIk5vbi1IaXNwYW5pYyBCbGFjayIpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gRXRobmljaXR5X0hpc3BhbmljLCBjb2xvciA9ICJIaXNwYW5pYyIpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gRXRobmljaXR5X090aGVyLCBjb2xvciA9ICJPdGhlciIpKSArCiAgbGFicyh5ID0gIlR1cm5vdXQgUmF0ZSIsIHRpdGxlID0gIlR1cm5vdXQgYnkgUmFjZSBhbmQgRXRobmljaXR5IiwgY29sb3IgPSAiUmFjZSBhbmQgRXRobmljaXR5IikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKQojZ2dzYXZlKCJkZW1vX2V0aC5wbmciKQoKZWR1Y2F0aW9uIDwtIGRlbW9fdHVybm91dCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBEYXRlKSkgKwogIGdlb21fbGluZShhZXMoeSA9IEVkdWNhdGlvbl9MZXNzX1RoYW5fSFMsIGNvbG9yID0gIkxlc3MgdGhhbiBIaWdoIFNjaG9vbCIpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gRWR1Y2F0aW9uX0hTX0dyYWQsIGNvbG9yID0gIkhpZ2ggU2Nob29sIEdyYWQiKSkgKwogIGdlb21fbGluZShhZXMoeSA9IEVkdWNhdGlvbl9Tb21lQ29sbGVnZV9Db2xsZWdlR3JhZCwgY29sb3IgPSAiU29tZSBDb2xsZWdlIG9yIENvbGxlZ2UgR3JhZCIpKSArCiAgZ2VvbV9saW5lKGFlcyh5ID0gRWR1Y2F0aW9uX1Bvc3RHcmFkdWF0ZSwgY29sb3IgPSAiUG9zdCBHcmFkdWF0ZSIpKSArCiAgbGFicyh5ID0gIlR1cm5vdXQgUmF0ZSIsIHRpdGxlID0gIlR1cm5vdXQgYnkgRWR1Y2F0aW9uIiwgY29sb3IgPSAiRWR1Y2F0aW9uIikgKwogIHRoZW1lX21pbmltYWwoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJib3R0b20iKQojZ2dzYXZlKCJkZW1vX2VkdS5wbmciKQpgYGAKClRoZSBvdGhlciB0dXJub3V0IGdyYXBocyBjYW4gYmUgZm91bmQgW2hlcmVdKCJodHRwczovL3B1YmxpYy50YWJsZWF1LmNvbS92aWV3cy9UdXJub3V0X2Rhc2hib2FyZC9EYXNoYm9hcmQyPzpkaXNwbGF5X2NvdW50PW4mOm9yaWdpbj12aXpfc2hhcmVfbGluayIpLgoKIyMgRWNvbm9teQoKYGBge3J9Cm5hdF9nZHBfcGxvdCA8LSBuYXRfZ2RwICU+JQogIGdncGxvdChhZXMoeCA9IERhdGUsIHkgPSBHRFApKSArCiAgZ2VvbV9saW5lKCkgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJHRFAgKEJpbGxpb25zKSIsIHRpdGxlID0gIk5hdGlvbmFsIEdEUCBvdmVyIFRpbWUsIFF1YXJ0ZXJseSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmdncGxvdGx5KG5hdF9nZHBfcGxvdCkKYGBgCgpgYGB7cn0KdXNfbWFwIDwtIG1hcF9kYXRhKG1hcCA9ICJzdGF0ZSIpICU+JQogIG11dGF0ZShyZWdpb24gPSBzdHJfdG9fdGl0bGUocmVnaW9uKSkKCmdkcF9tYXAgPC0gdXNfbWFwICU+JQogIGxlZnRfam9pbihzdGF0ZV9nZHBfZW1wbG95bWVudCwgYnkgPSBjKCJyZWdpb24iID0gIlN0YXRlIikpICU+JQogIGZpbHRlcihUeXBlX29mX1ZhbHVlID09ICJHcm9zcyBkb21lc3RpYyBwcm9kdWN0IChHRFApIikKCnBfdGVzdF8yIDwtIGdkcF9tYXAgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCkpICsKICBnZW9tX3BvbHlnb24oYWVzKGZpbGwgPSAoVmFsdWUvMTAwMCkpKSArCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAiYWxpY2VibHVlIiwgaGlnaCA9ICJtaWRuaWdodGJsdWUiLCBuYW1lID0gIkdEUCAoQmlsbGlvbnMpIikgKwogIGNvb3JkX21hcCgicG9seWNvbmljIikgKwogIHRoZW1lX21hcCgpICsKICBnZ3RpdGxlKCJHRFAgaW4gezE5OTcgKyBmcmFtZX0iKSArCiAgdHJhbnNpdGlvbl9tYW51YWwoWWVhcikKCiNhbmltYXRlKHBfdGVzdF8yLCBuZnJhbWVzID0gNTApCiNhbmltX3NhdmUoInN0YXRlX2dkcC5naWYiKQpgYGAKCmBgYHtyfQplbXBsb3ltZW50X21hcCA8LSB1c19tYXAgJT4lCiAgbGVmdF9qb2luKHN0YXRlX2dkcF9lbXBsb3ltZW50LCBieSA9IGMoInJlZ2lvbiIgPSAiU3RhdGUiKSkgJT4lCiAgZmlsdGVyKFR5cGVfb2ZfVmFsdWUgPT0gIlRvdGFsIEVtcGxveW1lbnQgKG51bWJlciBvZiBqb2JzKSIpCgpwX3Rlc3RfMiA8LSBnZHBfbWFwICU+JQogIGdncGxvdChhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gZ3JvdXApKSArCiAgZ2VvbV9wb2x5Z29uKGFlcyhmaWxsID0gKFZhbHVlKSkpICsKICBzY2FsZV9maWxsX2dyYWRpZW50KGxvdyA9ICJob25leWRldyIsIGhpZ2ggPSAiZGFya3NsYXRlZ3JheSIsIG5hbWUgPSAiTnVtYmVyIG9mIEpvYnMiKSArCiAgY29vcmRfbWFwKCJwb2x5Y29uaWMiKSArCiAgdGhlbWVfbWFwKCkgKwogIGdndGl0bGUoIkVtcGxveW1lbnQgaW4gezE5OTcgKyBmcmFtZX0iKSArCiAgdHJhbnNpdGlvbl9tYW51YWwoWWVhcikKCiNhbmltYXRlKHBfdGVzdF8yLCBuZnJhbWVzID0gNTApCiNhbmltX3NhdmUoInN0YXRlX2VtcGxveW1lbnQuZ2lmIikKYGBgCgojIyBXZWF0aGVyCmBgYHtyfQpuYXRfdHVybm91dF9mb3JfcGxvdCA8LSBuYXRfdHVybm91dCAlPiUKICBmaWx0ZXIoWWVhciA+IDE4OTUpICU+JQogIG11dGF0ZShEYXRlID0gYXMuRGF0ZShhcy5jaGFyYWN0ZXIoWWVhciksICIlWSIpKQoKIyB0dXJub3V0X3BsdXNfd2VhdGhlciA8LSBuYXRfdHVybm91dCAlPiUKIyAgIGZpbHRlcihZZWFyID4gMTg5NSkgJT4lCiMgICBtdXRhdGUoRGF0ZSA9IGFzLkRhdGUoYXMuY2hhcmFjdGVyKFllYXIpLCAiJVkiKSkgJT4lCiMgICBmdWxsX2pvaW4obmF0X3ByZWNpcCwgYnkgPSAiRGF0ZSIpICU+JQojICAgKERhdGUpCgpmaWcgPC0gcGxvdF9seShuYXRfcHJlY2lwKQoKZmlnIDwtIGZpZyAlPiUKICBhZGRfdHJhY2UoeCA9IH5EYXRlLCB5ID0gflByZWNpcGl0YXRpb24sIHR5cGUgPSAic2NhdHRlciIsIG1vZGUgPSAibGluZXMiLCBuYW1lID0gIk5vdmVtYmVyIFByZWNpcGlhdGlvbiIpCgpmaWcgPC0gZmlnICU+JQogIGFkZF90cmFjZShuYXRfdHVybm91dF9mb3JfcGxvdCwgeCA9IH5uYXRfdHVybm91dF9mb3JfcGxvdCREYXRlLCB5ID0gfm5hdF90dXJub3V0X2Zvcl9wbG90JFR1cm5vdXQsIG5hbWUgPSAiVHVybm91dCIsIHR5cGUgPSAic2NhdHRlciIsIHlheGlzID0gInkyIiwgbW9kZSA9ICJsaW5lcyIpCgpmaWcgPC0gZmlnICU+JSBsYXlvdXQoCiAgdGl0bGUgPSAiUHJlY2lwaXRhdGlvbiBhbmQgV2VhdGhlciIsIAogIHhheGlzID0gbGlzdCh0aXRsZSA9ICJEYXRlIiksCiAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIlByZWNpcGl0YXRpb24iKSwKICB5YXhpczIgPSBsaXN0KG92ZXJsYXlpbmcgPSAieSIsIHNpZGUgPSAicmlnaHQiLCB0aXRsZSA9ICJUdXJub3V0IFJhdGUiKSwKICBob3Zlcm1vZGUgPSAieCIKKQpmaWcKYGBgCgpgYGB7cn0KbmF0X3ByZWNpcF9wbG90IDwtIG5hdF9wcmVjaXAgJT4lCiAgZ2dwbG90KGFlcyh4ID0gRGF0ZSwgeSA9IFByZWNpcGl0YXRpb24pKSArCiAgZ2VvbV9saW5lKCkgKwogIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIlByZWNpcGl0YXRpb24iLCBzZWMuYXhpcyA9IHNlY19heGlzKH4uKjEwLCBuYW1lID0gIlR1cm5vdXQiKSkgKwogIHNjYWxlX3hfZGF0ZShicmVha3MgPSAnMjUgeWVhcnMnLCBkYXRlX2xhYmVscyA9ICIlWSIpICsKICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiUHJlY2lwaXRhdGlvbiIsIHRpdGxlID0gIk5vdmVtYmVyIFByZWNpcGl0YXRpb24iKSArCiAgdGhlbWVfbWluaW1hbCgpCgpnZ3Bsb3RseShuYXRfcHJlY2lwX3Bsb3QpCmBgYAoKYGBge3J9CndlYXRoZXJfbWFwIDwtIHVzX21hcCAlPiUKICBsZWZ0X2pvaW4oc3RhdGVfd2VhdGhlciwgYnkgPSBjKCJyZWdpb24iID0gIlN0YXRlIikpCgpwX3dlYXRoZXIgPC0gd2VhdGhlcl9tYXAgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbG9uZywgeSA9IGxhdCwgZ3JvdXAgPSBncm91cCkpICsKICBnZW9tX3BvbHlnb24oYWVzKGZpbGwgPSBQcmVjaXBpdGF0aW9uKSkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gImZsb3JhbHdoaXRlIiwgaGlnaCA9ICJkYXJrcmVkIiwgbmFtZSA9ICJQcmVjaXBpdGF0aW9uIChJbikiKSArCiAgY29vcmRfbWFwKCJwb2x5Y29uaWMiKSArCiAgdGhlbWVfbWFwKCkgKwogIGdndGl0bGUoIk5vdmVtYmVyIFByZWNpcGl0YXRpb24gaW4gezE4OTQgKyBmcmFtZX0iKSArCiAgdHJhbnNpdGlvbl9tYW51YWwoRGF0ZSkKCiNhbmltYXRlKHBfd2VhdGhlciwgbmZyYW1lcyA9IDIwMCkKI2FuaW1fc2F2ZSgic3RhdGVfd2VhdGhlci5naWYiKQpgYGAKCiMgRURBCgojIyBUdXJub3V0CgpgYGB7cn0KIyBJbml0aWFsIFRpbWUgU2VyaWVzIFBsb3QKbmF0X3R1cm5vdXRfcGxvdCA8LSBuYXRfdHVybm91dCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBZZWFyLCB5ID0gVHVybm91dCkpICsKICBnZW9tX2xpbmUoKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfY29tbWEoc3VmZml4ID0gJyUnKSkgKwogIGxhYnModGl0bGUgPSAiTmF0aW9uYWwgVHVybm91dCBPdmVyIFRpbWUiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpnZ3Bsb3RseShuYXRfdHVybm91dF9wbG90KQpgYGAKCmBgYHtyfQojIFRTIE9iamVjdAp0dXJub3V0X3RzIDwtIHRzKG5hdF90dXJub3V0JFR1cm5vdXQsIHN0YXJ0ID0gMTc4OCwgZnJlcXVlbmN5ID0gMC41KQpgYGAKCmBgYHtyfQojIExhZyBQbG90CmdnbGFncGxvdCh0dXJub3V0X3RzLCBsYWdzID0gMTIsIGRvLmxpbmVzID0gRkFMU0UpCmBgYAoKYGBge3J9CiMgRGVjb21wb3NlZCBQbG90CiMgTm90IGFibGUgdG8gZGVjb21wb3NlIC0gZmV3ZXIgdGhhbiAyIHBlcmlvZHMgYmVjYXVzZSBpdCdzIGV2ZXJ5IDIgeWVhcnMKIyBDYW4gc2VlIHRoZSB0cmVuZCBmcm9tIHBsb3R0aW5nIHByZXNpZGVudGlhbCBhbmQgbWlkdGVybSBzZXBhcmF0ZWx5CgpuYXRfdHVybm91dF9wbG90X2RlY29tcG9zZWQgPC0gbmF0X3R1cm5vdXQgJT4lCiAgZ2dwbG90KGFlcyh4ID0gWWVhciwgeSA9IFR1cm5vdXQpKSArCiAgZ2VvbV9saW5lKGFlcyhjb2xvciA9IFR5cGUpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfY29tbWEoc3VmZml4ID0gJyUnKSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJkYXJrZ3JlZW4iLCAicHVycGxlIikpICsKICBsYWJzKHRpdGxlID0gIk5hdGlvbmFsIFR1cm5vdXQgT3ZlciBUaW1lIC0gVHJlbmQgTGluZXMiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpnZ3Bsb3RseShuYXRfdHVybm91dF9wbG90X2RlY29tcG9zZWQpCgpgYGAKCmBgYHtyfQojIEFDRiBhbmQgUEFDRgp0dXJub3V0X2FjZiA8LSBnZ0FjZih0dXJub3V0X3RzLCAyMCkgKwogIGxhYnMoeCA9ICJMYWciLCB5ID0gIkFDRiIsIHRpdGxlID0gIlR1cm5vdXQgQUNGIFBsb3QiKSArCiAgdGhlbWVfbWluaW1hbCgpCgp0dXJub3V0X3BhY2YgPC0gZ2dQYWNmKHR1cm5vdXRfdHMsIDIwKSArCiAgbGFicyh4ID0gIkxhZyIsIHkgPSAiUEFDRiIsIHRpdGxlID0gIlR1cm5vdXQgUEFDRiBQbG90IikgKwogIHRoZW1lX21pbmltYWwoKQoKZ3JpZC5hcnJhbmdlKHR1cm5vdXRfYWNmLCB0dXJub3V0X3BhY2YsIG5jb2wgPSAyKQpgYGAKCmBgYHtyfQojIEFERiBUZXN0CnRzZXJpZXM6OmFkZi50ZXN0KHR1cm5vdXRfdHMpCmBgYAoKYGBge3J9CiMgRGlmZmVyZW5jZWQvTG9nIFRyYW5zZm9ybWVkCnAxIDwtIGF1dG9wbG90KHR1cm5vdXRfdHMpICsKICBsYWJzKHggPSAiWWVhciIsIHkgPSAiVHVybm91dCIsIHRpdGxlID0gIk9yaWdpbmFsIFR1cm5vdXQiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMiA8LSBhdXRvcGxvdChkaWZmKHR1cm5vdXRfdHMpKSArCiAgbGFicyh4ID0gIlllYXIiLCB5ID0gIkRpZmYoVHVybm91dCkiLCB0aXRsZSA9ICJGaXJzdC1PcmRlciBEaWZmZXJlbmNlZCBUdXJub3V0IikgKwogIHRoZW1lX21pbmltYWwoKQoKcDMgPC0gYXV0b3Bsb3QobG9nKHR1cm5vdXRfdHMpKSArCiAgbGFicyh4ID0gIlllYXIiLCB5ID0gIkxvZyhUdXJub3V0KSIsIHRpdGxlID0gIkxvZy1UcmFuc2Zvcm1lZCBUdXJub3V0IikgKwogIHRoZW1lX21pbmltYWwoKQoKZ3JpZC5hcnJhbmdlKHAxLCBwMiwgcDMsIG5jb2wgPSAxKQpgYGAKCmBgYHtyfQojIEFDRiBDb21wYXJlCnAxX2FjZiA8LSBnZ0FjZih0dXJub3V0X3RzLCAyMCkgKwogIGxhYnMoeCA9ICJMYWciLCB5ID0gIkFDRiIsIHRpdGxlID0gIk9yaWdpbmFsIFR1cm5vdXQgQUNGIFBsb3QiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMl9hY2YgPC0gZ2dBY2YoZGlmZih0dXJub3V0X3RzKSwgMjApICsKICBsYWJzKHggPSAiTGFnIiwgeSA9ICJBQ0YiLCB0aXRsZSA9ICJGaXJzdC1PcmRlciBEaWZmZXJlbmNlZCBUdXJub3V0IEFDRiBQbG90IikgKwogIHRoZW1lX21pbmltYWwoKQoKcDNfYWNmIDwtIGdnQWNmKGxvZyh0dXJub3V0X3RzKSwgMjApICsKICBsYWJzKHggPSAiTGFnIiwgeSA9ICJBQ0YiLCB0aXRsZSA9ICJMb2ctVHJhbnNmb3JtZWQgVHVybm91dCBBQ0YgUGxvdCIpICsKICB0aGVtZV9taW5pbWFsKCkKCmdyaWQuYXJyYW5nZShwMV9hY2YsIHAyX2FjZiwgcDNfYWNmLCBuY29sID0gMSkKYGBgCgpgYGB7cn0KIyBNb3ZpbmcgQXZlcmFnZSBTbW9vdGhpbmcKbTUgPC0gYXV0b3Bsb3QodHVybm91dF90cywgY29sb3IgPSAnZGFya2JsdWUnKSArCiAgYXV0b2xheWVyKG1hKHR1cm5vdXRfdHMsIDUpLCBjb2xvciA9ICdyZWQnKSArCiAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIlR1cm5vdXQgUmF0ZSIsIHRpdGxlID0gIlR1cm5vdXQgKE1BLTUpIikgKwogIHRoZW1lX21pbmltYWwoKQoKbTEwIDwtIGF1dG9wbG90KHR1cm5vdXRfdHMsIGNvbG9yID0gJ2RhcmtibHVlJykgKwogIGF1dG9sYXllcihtYSh0dXJub3V0X3RzLCAxMCksIGNvbG9yID0gJ3JlZCcpICsKICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiVHVybm91dCBSYXRlIiwgdGl0bGUgPSAiVHVybm91dCAoTUEtMTApIikgKwogIHRoZW1lX21pbmltYWwoKSAKCm0yMCA8LSBhdXRvcGxvdCh0dXJub3V0X3RzLCBjb2xvciA9ICdkYXJrYmx1ZScpICsKICBhdXRvbGF5ZXIobWEodHVybm91dF90cywgMjApLCBjb2xvciA9ICdyZWQnKSArCiAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIlR1cm5vdXQgUmF0ZSIsIHRpdGxlID0gIlR1cm5vdXQgKE1BLTIwKSIpICsKICB0aGVtZV9taW5pbWFsKCkgCiAgCm01MCA8LSBhdXRvcGxvdCh0dXJub3V0X3RzLCBjb2xvciA9ICdkYXJrYmx1ZScpICsKICBhdXRvbGF5ZXIobWEodHVybm91dF90cywgNTApLCBjb2xvciA9ICdyZWQnKSArCiAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIlR1cm5vdXQgUmF0ZSIsIHRpdGxlID0gIlR1cm5vdXQgKE1BLTUwKSIpICsKICB0aGVtZV9taW5pbWFsKCkgCgpncmlkLmFycmFuZ2UobTUsIG0xMCwgbTIwLCBtNTAsIG5yb3cgPSAyKQpgYGAKCiMjIEVjb25vbWljIENvbmRpdGlvbnMKCmBgYHtyfQojIEluaXRpYWwgVGltZSBTZXJpZXMgUGxvdApuYXRfZ2RwX3BsdCA8LSBuYXRfZ2RwICU+JQogIGdncGxvdChhZXMoeCA9IERhdGUsIHkgPSBHRFApKSArCiAgZ2VvbV9saW5lKCkgKwogIGxhYnModGl0bGUgPSAiTmF0aW9uYWwgR0RQIE92ZXIgVGltZSIpICsKICB0aGVtZV9taW5pbWFsKCkKCmdncGxvdGx5KG5hdF9nZHBfcGx0KQpgYGAKCmBgYHtyfQojIFRTIE9iamVjdApnZHBfdHMgPC0gdHMobmF0X2dkcCRHRFAsIHN0YXJ0ID0gYygxOTQ3LCAxKSwgZnJlcXVlbmN5ID0gNCkKYGBgCgpgYGB7cn0KIyBMYWcgUGxvdApnZ2xhZ3Bsb3QoZ2RwX3RzLCBsYWdzID0gMTIsIGRvLmxpbmVzID0gRkFMU0UpCmBgYAoKYGBge3J9CiMgRGVjb21wb3NlZCBQbG90CmRlY29tcG9zZWRfZ2RwID0gZGVjb21wb3NlKGdkcF90cywgIm11bHRpcGxpY2F0aXZlIikKYXV0b3Bsb3QoZGVjb21wb3NlZF9nZHApCmBgYAoKYGBge3J9CiMgQUNGIGFuZCBQQUNGCmdkcF9hY2YgPC0gZ2dBY2YoZ2RwX3RzLCAzMCkgKwogIGxhYnMoeCA9ICJMYWciLCB5ID0gIkFDRiIsIHRpdGxlID0gIkdEUCBBQ0YgUGxvdCIpICsKICB0aGVtZV9taW5pbWFsKCkKCmdkcF9wYWNmIDwtIGdnUGFjZihnZHBfdHMsIDMwKSArCiAgbGFicyh4ID0gIkxhZyIsIHkgPSAiUEFDRiIsIHRpdGxlID0gIkdEUCBQQUNGIFBsb3QiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpncmlkLmFycmFuZ2UoZ2RwX2FjZiwgZ2RwX3BhY2YsIG5jb2wgPSAyKQpgYGAKCmBgYHtyfQojIEFERiBUZXN0CnRzZXJpZXM6OmFkZi50ZXN0KGdkcF90cykKYGBgCgpgYGB7cn0KIyBEaWZmZXJlbmNlZC9Mb2cgVHJhbnNmb3JtZWQKcDExIDwtIGF1dG9wbG90KGdkcF90cykgKwogIGxhYnMoeCA9ICJZZWFyIiwgeSA9ICJHRFAiLCB0aXRsZSA9ICJPcmlnaW5hbCBHRFAiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwMjIgPC0gYXV0b3Bsb3QoZGlmZihnZHBfdHMpKSArCiAgbGFicyh4ID0gIlllYXIiLCB5ID0gIkRpZmYoR0RQKSIsIHRpdGxlID0gIkZpcnN0LU9yZGVyIERpZmZlcmVuY2VkIEdEUCIpICsKICB0aGVtZV9taW5pbWFsKCkKCnAzMyA8LSBhdXRvcGxvdChsb2coZ2RwX3RzKSkgKwogIGxhYnMoeCA9ICJZZWFyIiwgeSA9ICJMb2coR0RQKSIsIHRpdGxlID0gIkxvZy1UcmFuc2Zvcm1lZCBHRFAiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpncmlkLmFycmFuZ2UocDExLCBwMjIsIHAzMywgbmNvbCA9IDEpCmBgYAoKYGBge3J9CiMgQUNGIENvbXBhcmUKcDExX2FjZiA8LSBnZ0FjZihnZHBfdHMsIDIwKSArCiAgbGFicyh4ID0gIkxhZyIsIHkgPSAiQUNGIiwgdGl0bGUgPSAiT3JpZ2luYWwgR0RQIEFDRiBQbG90IikgKwogIHRoZW1lX21pbmltYWwoKQoKcDIyX2FjZiA8LSBnZ0FjZihkaWZmKGdkcF90cyksIDIwKSArCiAgbGFicyh4ID0gIkxhZyIsIHkgPSAiQUNGIiwgdGl0bGUgPSAiRmlyc3QtT3JkZXIgRGlmZmVyZW5jZWQgR0RQIEFDRiBQbG90IikgKwogIHRoZW1lX21pbmltYWwoKQoKcDMzX2FjZiA8LSBnZ0FjZihsb2coZ2RwX3RzKSwgMjApICsKICBsYWJzKHggPSAiTGFnIiwgeSA9ICJBQ0YiLCB0aXRsZSA9ICJMb2ctVHJhbnNmb3JtZWQgR0RQIEFDRiBQbG90IikgKwogIHRoZW1lX21pbmltYWwoKQoKZ3JpZC5hcnJhbmdlKHAxMV9hY2YsIHAyMl9hY2YsIHAzM19hY2YsIG5jb2wgPSAxKQpgYGAKCgpgYGB7cn0KIyBNb3ZpbmcgQXZlcmFnZSBTbW9vdGhpbmcKbTUgPC0gYXV0b3Bsb3QoZ2RwX3RzLCBjb2xvciA9ICdkYXJrYmx1ZScsIHNpemUgPSAwLjc1KSArCiAgYXV0b2xheWVyKG1hKGdkcF90cywgNSksIGNvbG9yID0gJ3JlZCcpICsKICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiR0RQIiwgdGl0bGUgPSAiTmF0aW9uYWwgR0RQIChNQS01KSIpICsKICB0aGVtZV9taW5pbWFsKCkKCm0yMCA8LSBhdXRvcGxvdChnZHBfdHMsIGNvbG9yID0gJ2RhcmtibHVlJywgc2l6ZSA9IDAuNzUpICsKICBhdXRvbGF5ZXIobWEoZ2RwX3RzLCAyMCksIGNvbG9yID0gJ3JlZCcpICsKICBsYWJzKHggPSAiRGF0ZSIsIHkgPSAiR0RQIiwgdGl0bGUgPSAiTmF0aW9uYWwgR0RQIChNQS0yMCkiKSArCiAgdGhlbWVfbWluaW1hbCgpIAoKbTUwIDwtIGF1dG9wbG90KGdkcF90cywgY29sb3IgPSAnZGFya2JsdWUnLCBzaXplID0gMC43NSkgKwogIGF1dG9sYXllcihtYShnZHBfdHMsIDUwKSwgY29sb3IgPSAncmVkJykgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJHRFAiLCB0aXRsZSA9ICJOYXRpb25hbCBHRFAgKE1BLTUwKSIpICsKICB0aGVtZV9taW5pbWFsKCkgCiAgCm0xMDAgPC0gYXV0b3Bsb3QoZ2RwX3RzLCBjb2xvciA9ICdkYXJrYmx1ZScsIHNpemUgPSAwLjc1KSArCiAgYXV0b2xheWVyKG1hKGdkcF90cywgMTAwKSwgY29sb3IgPSAncmVkJykgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJHRFAiLCB0aXRsZSA9ICJOYXRpb25hbCBHRFAgKE1BLTEwMCkiKSArCiAgdGhlbWVfbWluaW1hbCgpIAoKZ3JpZC5hcnJhbmdlKG01LCBtMjAsIG01MCwgbTEwMCwgbnJvdyA9IDIpCmBgYAoKCiMjIFdlYXRoZXIKCmBgYHtyfQojIEluaXRpYWwgVGltZSBTZXJpZXMgUGxvdApuYXRfcHJlY2lwX3BsdCA8LSBuYXRfcHJlY2lwICU+JQogIGdncGxvdChhZXMoeCA9IERhdGUsIHkgPSBQcmVjaXBpdGF0aW9uKSkgKwogIGdlb21fbGluZSgpICsKICBsYWJzKHRpdGxlID0gIk5hdGlvbmFsIFByZWNpcGl0YXRpb24gT3ZlciBUaW1lIikgKwogIHRoZW1lX21pbmltYWwoKQoKZ2dwbG90bHkobmF0X3ByZWNpcF9wbHQpCmBgYAoKYGBge3J9CiMgVFMgT2JqZWN0CnByZWNpcF90cyA8LSB0cyhuYXRfcHJlY2lwJFByZWNpcGl0YXRpb24sIHN0YXJ0ID0gMTg5NSwgZnJlcXVlbmN5ID0gMSkKYGBgCgpgYGB7cn0KIyBMYWcgUGxvdApnZ2xhZ3Bsb3QocHJlY2lwX3RzLCBsYWdzID0gMTIsIGRvLmxpbmVzID0gRkFMU0UpCmBgYAoKYGBge3J9CiMgRGVjb21wb3NlZCBQbG90CiMgTm90IGFibGUgdG8gZG8gLSBvbmx5IG9uZSBldmVyeSB5ZWFyCmBgYAoKYGBge3J9CiMgQUNGIGFuZCBQQUNGCnByZWNpcF9hY2YgPC0gZ2dBY2YocHJlY2lwX3RzLCAzMCkgKwogIGxhYnMoeCA9ICJMYWciLCB5ID0gIkFDRiIsIHRpdGxlID0gIlByZWNpcGl0YXRpb24gQUNGIFBsb3QiKSArCiAgdGhlbWVfbWluaW1hbCgpCgpwcmVjaXBfcGFjZiA8LSBnZ1BhY2YocHJlY2lwX3RzLCAzMCkgKwogIGxhYnMoeCA9ICJMYWciLCB5ID0gIlBBQ0YiLCB0aXRsZSA9ICJQcmVjaXBpdGF0aW9uIFBBQ0YgUGxvdCIpICsKICB0aGVtZV9taW5pbWFsKCkKCmdyaWQuYXJyYW5nZShwcmVjaXBfYWNmLCBwcmVjaXBfcGFjZiwgbmNvbCA9IDIpCmBgYAoKYGBge3J9CiMgQURGIFRlc3QKdHNlcmllczo6YWRmLnRlc3QocHJlY2lwX3RzKQpgYGAKCmBgYHtyfQojIE1vdmluZyBBdmVyYWdlIFNtb290aGluZwptNSA8LSBhdXRvcGxvdChwcmVjaXBfdHMsIGNvbG9yID0gJ2RhcmtibHVlJywgc2l6ZSA9IDAuNzUpICsKICBhdXRvbGF5ZXIobWEocHJlY2lwX3RzLCA1KSwgY29sb3IgPSAncmVkJykgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJQcmVjaXBpdGF0aW9uIiwgdGl0bGUgPSAiTmF0aW9uYWwgUHJlY2lwaXRhdGlvbiAoTUEtNSkiKSArCiAgdGhlbWVfbWluaW1hbCgpCgptMTAgPC0gYXV0b3Bsb3QocHJlY2lwX3RzLCBjb2xvciA9ICdkYXJrYmx1ZScsIHNpemUgPSAwLjc1KSArCiAgYXV0b2xheWVyKG1hKHByZWNpcF90cywgMTApLCBjb2xvciA9ICdyZWQnKSArCiAgbGFicyh4ID0gIkRhdGUiLCB5ID0gIlByZWNpcGl0YXRpb24iLCB0aXRsZSA9ICJOYXRpb25hbCBQcmVjaXBpdGF0aW9uIChNQS0xMCkiKSArCiAgdGhlbWVfbWluaW1hbCgpIAoKbTIwIDwtIGF1dG9wbG90KHByZWNpcF90cywgY29sb3IgPSAnZGFya2JsdWUnLCBzaXplID0gMC43NSkgKwogIGF1dG9sYXllcihtYShwcmVjaXBfdHMsIDIwKSwgY29sb3IgPSAncmVkJykgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJQcmVjaXBpdGF0aW9uIiwgdGl0bGUgPSAiTmF0aW9uYWwgUHJlY2lwaXRhdGlvbiAoTUEtMjApIikgKwogIHRoZW1lX21pbmltYWwoKSAKICAKbTUwIDwtIGF1dG9wbG90KHByZWNpcF90cywgY29sb3IgPSAnZGFya2JsdWUnLCBzaXplID0gMC43NSkgKwogIGF1dG9sYXllcihtYShwcmVjaXBfdHMsIDUwKSwgY29sb3IgPSAncmVkJykgKwogIGxhYnMoeCA9ICJEYXRlIiwgeSA9ICJQcmVjaXBpdGF0aW9uIiwgdGl0bGUgPSAiTmF0aW9uYWwgUHJlY2lwaXRhdGlvbiAoTUEtNTApIikgKwogIHRoZW1lX21pbmltYWwoKSAKCmdyaWQuYXJyYW5nZShtNSwgbTEwLCBtMjAsIG01MCwgbnJvdyA9IDIpCmBgYAoK